package com.kindness.frate.pull;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.drawable.AnimationDrawable;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.kindness.frate.R;
import com.kindness.frate.animate.AnimateUtils;
import com.kindnesslibrary.adapter.CommonAdapter;
import com.kindnesslibrary.util.EnableLinearManager;
import com.kindnesslibrary.util.WidgetUtil;

/**
 * Created by Administrator on 2017/7/25 0025.
 * 下拉刷新
 */
public class PullRefreshRecyclerView extends LinearLayout {

    /**
     * 头部、尾部
     */
    View headerView, footerView, footerRefreshing, footerFinish;
    PullRefreshStepView mFirstView, mSecondView, mThirdView;
    TextView tvPullRefreshHeaderTitle;
    private int headerViewHeight;

    // 数据
    private RecyclerView recyclerView;

    // 动画
    private ValueAnimator animator;

    private static final int RATIO = 3; // 下拉比例
    private float startY; // 起始位置
    private float offsetY; // 位移大小
    private boolean isRecord; // 是否记录
    public static final int DONE = 0; // 完成下拉
    public static final int PULL_TO_REFRESH = 1; // 下拉刷新
    public static final int RELEASE_TO_REFRESH = 2; // 释放下拉
    private int pullState; // 下拉状态
    private EnableLinearManager enableLinearManager; // 是否启动拦截recyclerview，让LinearLayout进行分发处理
    // 图片动画效果
    private AnimationDrawable secondAnim;
    private AnimationDrawable thirdAnim;
    // 上下拉回调
    private PullRefreshListener pullRefreshListener;
    private boolean isLoadMore = false;

    public PullRefreshRecyclerView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        setOverScrollMode(View.OVER_SCROLL_NEVER);
        headerView = LayoutInflater.from(getContext()).inflate(R.layout.pull_refresh_header_layout, null, false);
        measureView(headerView);
        addView(headerView);
        headerViewHeight = headerView.getMeasuredHeight();
        headerView.setPadding(0, -headerViewHeight, 0, 0);

        mFirstView = (PullRefreshStepView) headerView.findViewById(R.id.first_view);
        mSecondView = (PullRefreshStepView) headerView.findViewById(R.id.second_view);
        mSecondView.setBackgroundResource(R.drawable.pull_to_refresh_second_anim);
        secondAnim = (AnimationDrawable) mSecondView.getBackground();
        mThirdView = (PullRefreshStepView) headerView.findViewById(R.id.third_view);
        mThirdView.setBackgroundResource(R.drawable.pull_to_refresh_third_anim);
        thirdAnim = (AnimationDrawable) mThirdView.getBackground();
        tvPullRefreshHeaderTitle = (TextView) headerView.findViewById(R.id.tv_pull_refresh_header_title);

        View view = LayoutInflater.from(getContext()).inflate(R.layout.pull_refresh_recyclerview_layout, this, true);
        recyclerView = (RecyclerView) view.findViewById(R.id.pull_refresh_recycler);

        footerView = LayoutInflater.from(getContext()).inflate(R.layout.pull_refresh_footer_layout, null, false);
        measureView(footerView);
        footerRefreshing = footerView.findViewById(R.id.footer_refreshing);
        footerFinish = footerView.findViewById(R.id.footer_finish);

        pullState = DONE;

        recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    if (WidgetUtil.isSlideToBottom(recyclerView)) {
                        if (pullRefreshListener != null && !isLoadMore) {
                            pullRefreshListener.onLoadMore();
                        }
                    }
                }
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
            }
        });

    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN: {
                if (WidgetUtil.getScollYDistance(recyclerView) == 0 && !isRecord) {
                    isRecord = true;
                    startY = ev.getY(); // 获取当前触摸的Y位置
                }
            }
            break;
            case MotionEvent.ACTION_MOVE: {
                float tempY = ev.getY();
                // 当recyclerview滑动至非顶端位置松手则isRecord为false，
                // 那么当recyclerView移动至顶端时startY需要重新记录.
                if (WidgetUtil.getScollYDistance(recyclerView) == 0 && !isRecord) {
                    isRecord = true;
                    startY = tempY;
                }
                // 如果是顶端，那么则开始下拉刷新
                if (WidgetUtil.getScollYDistance(recyclerView) == 0) {
                    offsetY = tempY - startY; // 计算偏移量
                    if (offsetY == 0) {
                        break;
                    }
                    //计算当前滑动的高度
                    float currentHeight = (-headerViewHeight + offsetY / RATIO);
                    //用当前滑动的高度和头部headerView的总高度进行比 计算出当前滑动的百分比 0到1
                    float currentProgress = 1 + currentHeight / headerViewHeight;
                    //如果当前百分比大于1了，将其设置为1，目的是让第一个状态的椭圆不再继续变大
                    currentProgress = currentProgress > 1 ? 1 : currentProgress;

                    if (pullState == DONE || pullState == PULL_TO_REFRESH) {
                        if (-headerViewHeight + offsetY / RATIO >= 0) {
                            pullState = PULL_TO_REFRESH;
                            changeHeaderByState();
                        } else {
                            changeHeaderByState();
                        }
                    }
                    if (pullState == RELEASE_TO_REFRESH) {
                        headerView.setPadding(0, (int) (offsetY / RATIO), 0, 0);
                        currentProgress = (1.f + currentProgress) > 1.f ? 1.f : (1.f + currentProgress);
                        mFirstView.setCurrentProgress(currentProgress);
                        mFirstView.postInvalidate();
                    } else {
                        headerView.setPadding(0, (int) (-headerViewHeight + offsetY / RATIO), 0, 0);
                        // 给第一个状态的View设置当前进度值
                        mFirstView.setCurrentProgress(currentProgress);
                        mFirstView.postInvalidate();
                    }
                }
                if (headerView.getPaddingTop() < -headerViewHeight && enableLinearManager != null) {
                    enableLinearManager.setScrollEnabled(true);
                }
            }
            break;
            case MotionEvent.ACTION_UP: {
                if (pullState != DONE && headerView.getPaddingTop() >= 0) {
                    creatExpendAnimator(headerView.getPaddingTop(), 0, 200);
                    pullState = RELEASE_TO_REFRESH;
                    changeHeaderByState();
                    if (pullRefreshListener != null) {
                        pullRefreshListener.onRefresh();
                    }
                } else {
                    creatExpendAnimator(headerView.getPaddingTop(), -headerViewHeight, 200);
                    pullState = DONE;
                    changeHeaderByState();
                }
                isRecord = false;
            }
            break;
        }
        return super.onTouchEvent(ev);
    }

    public void setAdapter(CommonAdapter adapter) {
        adapter.addFootView(footerView);
        recyclerView.setAdapter(adapter);
    }

    public void setLayoutManager(RecyclerView.LayoutManager layoutManager) {
        recyclerView.setLayoutManager(layoutManager);
    }

    public void setPullRefreshListener(PullRefreshListener pullRefreshListener) {
        this.pullRefreshListener = pullRefreshListener;
    }

    /**
     * 根据状态改变headerView的动画和文字显示
     */
    private void changeHeaderByState() {
        switch (pullState) {
            case PULL_TO_REFRESH: {
                if (-headerViewHeight + offsetY / RATIO >= 0) {
                    tvPullRefreshHeaderTitle.setText(getContext().getResources().getString(R.string.release_refresh));
                    mFirstView.setVisibility(View.GONE);
                    mSecondView.setVisibility(View.VISIBLE);
                    secondAnim.start();
                    mThirdView.setVisibility(View.GONE);
                    thirdAnim.stop();
                } else {
                    tvPullRefreshHeaderTitle.setText(getContext().getResources().getString(R.string.pull_refresh));
                    mFirstView.setVisibility(View.VISIBLE);
                    mSecondView.setVisibility(View.GONE);
                    secondAnim.stop();
                    mThirdView.setVisibility(View.GONE);
                    thirdAnim.stop();
                }
            }
            break;
            case RELEASE_TO_REFRESH: {
                tvPullRefreshHeaderTitle.setText(getContext().getResources().getString(R.string.refreshing));
                mFirstView.setVisibility(View.GONE);
                mSecondView.setVisibility(View.GONE);
                secondAnim.stop();
                mThirdView.setVisibility(View.VISIBLE);
                thirdAnim.start();
            }
            break;
            case DONE: {
                tvPullRefreshHeaderTitle.setText(getContext().getResources().getString(R.string.pull_refresh));
                mFirstView.setVisibility(View.VISIBLE);
                mSecondView.setVisibility(View.GONE);
                secondAnim.stop();
                mThirdView.setVisibility(View.GONE);
                thirdAnim.stop();
            }
            break;
        }
    }

    public int getPullState() {
        return pullState;
    }

    /**
     * 刷新完成
     */
    public void refreshComplete() {
        isLoadMore = false;
        pullState = DONE;
        creatExpendAnimator(headerView.getPaddingTop(), -headerViewHeight, 200);
        footerRefreshing.setVisibility(VISIBLE);
        footerFinish.setVisibility(GONE);
        changeHeaderByState();
    }

    /**
     * 加载完成
     */
    public void loadComplete() {
        isLoadMore = true;
        footerRefreshing.setVisibility(GONE);
        footerFinish.setVisibility(VISIBLE);
        recyclerView.smoothScrollToPosition(recyclerView.getAdapter().getItemCount());
    }

    /**
     * 动画效果
     *
     * @param start    起点
     * @param end      终点
     * @param duration 时间
     */
    private void creatExpendAnimator(float start, float end, int duration) {
        clearAnimotor();
        animator = new AnimateUtils().valueAnimateChange(start, end, duration, animation -> {
            float value = (float) animation.getAnimatedValue();
            headerView.setPadding(0, (int) value, 0, 0);
        });
    }

    /**
     * 清除动画
     */
    private void clearAnimotor() {
        if (animator != null) {
            animator.cancel();
        }
    }

    /**
     * 测量控件
     *
     * @param child
     */
    private void measureView(View child) {
        ViewGroup.LayoutParams p = child.getLayoutParams();
        if (p == null) {
            p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.WRAP_CONTENT);
        }
        int childWidthSpec = ViewGroup.getChildMeasureSpec(0, 0 + 0, p.width);
        int lpHeight = p.height;
        int childHeightSpec;
        if (lpHeight > 0) {
            childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight,
                    MeasureSpec.EXACTLY);
        } else {
            childHeightSpec = MeasureSpec.makeMeasureSpec(0,
                    MeasureSpec.UNSPECIFIED);
        }
        child.measure(childWidthSpec, childHeightSpec);
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        if (enableLinearManager == null) {
            if (recyclerView.getLayoutManager() instanceof EnableLinearManager) {
                enableLinearManager = (EnableLinearManager) recyclerView.getLayoutManager();
            }
        }
    }

    public RecyclerView getRecyclerView(){
        return recyclerView;
    }

}
